// Webpack配置文件
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const WorkboxPlugin = require('workbox-webpack-plugin');

// 检查是否为生产环境
const isProduction = process.env.NODE_ENV === 'production';
const isDevelopment = !isProduction;

// 直接在webpack配置中定义所需的配置
const version = process.env.APP_VERSION || 'v2.2';
const apiUrl = process.env.API_URL || '/';

// 构建日期和时间戳
const buildDate = new Date().toISOString().split('T')[0];
const buildTimestamp = Date.now();

// 创建webpack配置对象
const webpackConfig = {
  // 入口文件 - 采用动态导入策略
  entry: {
    app: {
      import: './src/js/app.js',
      dependOn: 'vendor',
    },
    install: './src/js/install.js',
    vendor: ['core-js/stable', 'regenerator-runtime/runtime'],
  },
  // 输出配置 - 增强长效缓存策略
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: isProduction ? 'js/[name].[contenthash:8].js' : 'js/[name].js',
    chunkFilename: isProduction ? 'js/chunks/[name].[contenthash:8].js' : 'js/chunks/[name].js',
    assetModuleFilename: 'assets/[hash:8][ext][query]',
    clean: {
      keep: /\/static\//, // 保留静态目录不清理
    },
    publicPath: '/',
  },
  // 模式
  mode: isProduction ? 'production' : 'development',

  // 模块解析
  resolve: {
    extensions: ['.js', '.jsx', '.json'],
    alias: {
      '@': path.resolve(__dirname, 'src'),
      '@modules': path.resolve(__dirname, 'src/js/modules'),
    },
  },
  // 模块规则
  module: {
    rules: [
      // JavaScript处理
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: [
              ['@babel/preset-env', {
                targets: 'defaults',
                useBuiltIns: 'usage',
                corejs: 3,
              }],
            ],
            plugins: ['@babel/plugin-transform-runtime'],
          },
        },
      },
      // CSS处理
      {
        test: /\.css$/,
        use: [
          isProduction ? MiniCssExtractPlugin.loader : 'style-loader',
          'css-loader',
          'postcss-loader',
        ],
      },
      // 图片处理
      {
        test: /\.(png|jpe?g|gif|svg)$/i,
        type: 'asset',
        generator: {
          filename: 'images/[hash][ext][query]',
        },
        parser: {
          dataUrlCondition: {
            maxSize: 8 * 1024, // 8kb
          },
        },
      },
      // 字体处理
      {
        test: /\.(woff|woff2|eot|ttf|otf)$/,
        type: 'asset/resource',
        generator: {
          filename: 'fonts/[hash][ext][query]',
        },
      },
    ],
  },
  // 插件
  plugins: [
    // 清理dist目录
    new CleanWebpackPlugin(),

    // 生成HTML文件
    new HtmlWebpackPlugin({
      template: './public/index.html',
      filename: 'index.html',
      chunks: ['runtime', 'vendor', 'common', 'app', 'install'],
      minify: isProduction ? {
        collapseWhitespace: true,
        removeComments: true,
        minifyCSS: true,
        minifyJS: true,
      } : false,
    }),

    // 复制静态文件
    new CopyWebpackPlugin({
      patterns: [
        {
          from: 'public/manifest.json',
          to: 'manifest.json',
        },
        {
          from: 'public/mock-data.json',
          to: 'mock-data.json',
        },
        {
          from: 'public/offline.html',
          to: 'offline.html',
        },
        {
          from: 'src/icons',
          to: 'icons',
        },
      ],
    }),

    // 提取CSS
    isProduction && new MiniCssExtractPlugin({
      filename: 'css/[name].[contenthash].css',
    }),

    // Workbox插件用于PWA功能 - 使用InjectManifest模式
    // 只在生产环境下使用InjectManifest，避免开发环境的多个实例错误
    isProduction && new WorkboxPlugin.InjectManifest({
      swSrc: './public/sw.js',
      swDest: 'sw.js',
      maximumFileSizeToCacheInBytes: 5 * 1024 * 1024, // 5MB
      dontCacheBustURLsMatching: /\.[0-9a-f]{8}\./, // 防止缓存破坏带有内容哈希的文件
      // 配置预缓存文件
      include: [
        /\.html$/,
        /\.css$/,
        /\.js$/,
        /manifest\.json$/,
        /icons\//,
        /mock-data\.json$/
      ],
      // 排除不需要缓存的文件
      exclude: [
        /\.map$/, // 源映射文件
        /sw\.js$/, // 避免缓存service worker自身
      ]
    }),

    // 环境变量注入
    new webpack.DefinePlugin({
      'process.env.APP_VERSION': JSON.stringify(version),
      'process.env.API_URL': JSON.stringify(apiUrl),
    }),

    // 开发环境HMR增强
    isDevelopment && new webpack.HotModuleReplacementPlugin(),
  ].filter(Boolean),

  // 优化配置 - 增强代码分割和性能
  optimization: {
    // 启用模块联邦支持未来的微前端架构
    moduleIds: isProduction ? 'deterministic' : 'named',
    chunkIds: isProduction ? 'deterministic' : 'named',
    runtimeChunk: {
      name: 'runtime',
    },
    minimize: isProduction,
    minimizer: [
      new TerserPlugin({
        // 启用多线程压缩以提高构建速度
        parallel: true,
        // 配置terser压缩选项
        terserOptions: {
          format: {
            comments: false, // 删除所有注释
          },
          compress: {
            drop_console: isProduction, // 生产环境下删除console语句
            drop_debugger: isProduction, // 生产环境下删除debugger语句
            dead_code: true, // 移除死代码
            unused: true, // 移除未使用的变量和函数
            join_vars: true, // 合并连续的变量声明
          },
          mangle: true,
          keep_classnames: false,
          keep_fnames: false,
        },
        extractComments: false,
      }),
      new CssMinimizerPlugin({
        parallel: true,
        minimizerOptions: {
          preset: [
            'default',
            {
              discardComments: { removeAll: true },
            },
          ],
        },
      }),
    ],
    splitChunks: {
      chunks: 'all',
      minSize: 20000, // 提取块的最小大小为20KB
      minRemainingSize: 0,
      minChunks: 1,
      maxAsyncRequests: 30,
      maxInitialRequests: 30,
      enforceSizeThreshold: 50000,
      cacheGroups: {
        vendor: {
          test: /[\\/]node_modules[\\/]/,
          name(module) {
            // 获取第三方库名称并自定义命名
            const packageName = module.context.match(/[\\/]node_modules[\\/](.*?)([\\/]|$)/)[1];
            return `vendors/${packageName.replace('@', '').replace('/', '.')}`;
          },
          priority: -10,
          reuseExistingChunk: true,
          enforceSizeThreshold: 50000,
        },
        common: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,
          name: 'common',
        },
        styles: {
          name: 'styles',
          test: /\.css$/,
          chunks: 'all',
          enforce: true,
          priority: -5,
        }
      },
    },

  },

  // 开发服务器配置
  devServer: {
    static: {
      directory: path.join(__dirname, 'public'),
      serveIndex: true,
      watch: true,
    },
    compress: true,
    port: 8080,
    hot: true,
    open: true,
    liveReload: true,
    client: {
      overlay: {
        errors: true,
        warnings: false,
      },
      progress: true,
      logging: 'info',
    },
    headers: {
      'Cache-Control': 'no-store, no-cache, must-revalidate, proxy-revalidate, max-age=0',
      Pragma: 'no-cache',
      Expires: '0',
      'Access-Control-Allow-Origin': '*',
    },
    historyApiFallback: true,
    devMiddleware: {
      stats: 'minimal',
    },
    allowedHosts: 'all',
  },
  // 性能提示
  performance: {
    hints: isProduction ? 'warning' : false,
  },
  // 缓存配置 - 提高构建性能
  cache: {
    type: 'filesystem',
    buildDependencies: {
      config: [__filename],
    },
    // 详细的缓存配置
    profile: true,
    store: 'pack',
    compression: 'gzip',
    version: buildDate, // 使用日期作为缓存版本号
    cacheDirectory: path.resolve(__dirname, '.webpack-cache'),
  },
  
  // Source Maps配置 - 提高调试体验
  devtool: isProduction ? 'source-map' : 'eval-cheap-module-source-map',

  // 性能优化
  performance: {
    hints: isProduction ? 'warning' : false,
    maxEntrypointSize: 512000, // 512KB
    maxAssetSize: 256000, // 256KB
    assetFilter: function(assetFilename) {
      return assetFilename.endsWith('.js') || assetFilename.endsWith('.css');
    },
  },

  // 并行构建配置
  parallelism: 4,

  //  experiments配置
  experiments: {
    backCompat: false,
    topLevelAwait: true,
    futureDefaults: false,
  },
};

// 导出webpack配置
module.exports = webpackConfig;
